package edu.thu.studio.ormdesigner.editor.dialog.tab.table.sub;

import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import edu.thu.studio.ormdesigner.common.AbstractDialog;
import edu.thu.studio.ormdesigner.common.CompositeFactory;
import edu.thu.studio.ormdesigner.model.domain.Domain;
import edu.thu.studio.ormdesigner.model.domain.DomainSet;
import edu.thu.studio.ormdesigner.model.orm.table.Column;
import edu.thu.studio.ormdesigner.util.Properties;
import edu.thu.studio.ormdesigner.util.DataTypeUtils;
import edu.thu.studio.ormdesigner.util.Utils;

public class ColumnDialog extends AbstractDialog {

	private Button primaryKeyCheck;
	private Button notNullCheck;
	private Text codeText;
	private Text nameText;
	private Text commentText;

	private boolean isPk;
	private boolean add;

	private Combo dataTypeCombo;
	private Text lengthText;
	private Text precisionText;

	private Combo domainCombo;

	private Button dataTypeRadio;
	private Button domainRadio;

	private Group inputGroup;
	private Group selectGroup;

	private DomainSet domainSet;
	private Column targetColumn;
	private Column returnColumn;
	private Domain copyDomain;

	private List<Column> targetColumnList;

	public ColumnDialog(Shell parentShell, DomainSet domainSet) {
		super(parentShell);
		this.domainSet = domainSet;
		this.returnColumn = new Column();
		this.copyDomain = new Domain();
	}

	public void setTargetColumn(Column targetColumn,
			List<Column> targetColumnList) {

		if (targetColumn == null) {
			this.setAdd(true);
		} else {
			this.targetColumn = targetColumn;
			this.isPk = targetColumn.getPrimary();

			this.setAdd(false);
		}
		this.targetColumnList = targetColumnList;
	}

	@Override
	protected void initLayout(GridLayout layout) {
		super.initLayout(layout);
		layout.numColumns = 1;
	}

	@Override
	protected void initialize(Composite composite) {

		Group groupCheck = CompositeFactory.createGroup(composite,
				Properties.diagram_label_table_column_baseinfo, 1, 2);

		this.primaryKeyCheck = CompositeFactory.createCheckbox(this,
				groupCheck, Properties.diagram_label_table_column_pk, false);
		this.notNullCheck = CompositeFactory.createCheckbox(this, groupCheck,
				Properties.diagram_label_table_column_null, false);
		this.codeText = CompositeFactory.createText(this, groupCheck,
				Properties.diagram_label_table_column_ccode, 1, 350, false,
				true);
		this.nameText = CompositeFactory.createText(this, groupCheck,
				Properties.diagram_label_table_column_cname, 1, 350, false,
				true);
		this.commentText = CompositeFactory.createTextArea(this, groupCheck,
				Properties.diagram_label_table_column_ccomment, 330, 100, 1,
				true);

		Group groupText = CompositeFactory.createGroup(composite,
				Properties.diagram_label_table_column_choose, 1, 2);
		this.dataTypeRadio = CompositeFactory.createRadio(this, groupText,
				Properties.diagram_label_table_column_datatype_radio);
		this.domainRadio = CompositeFactory.createRadio(this, groupText,
				Properties.diagram_label_table_column_domain_radio);

		inputGroup = CompositeFactory.createGroup(groupText, "", 1, 2);

		this.dataTypeCombo = CompositeFactory.createReadOnlyCombo(this,
				inputGroup, Properties.diagram_label_table_column_datatype,
				this.getNumColumns() - 1, -1);
		this.lengthText = CompositeFactory.createNumText(this, inputGroup,
				Properties.diagram_label_table_column_length, true);
		this.precisionText = CompositeFactory.createNumText(this, inputGroup,
				Properties.diagram_label_table_column_precision, true);

		selectGroup = CompositeFactory.createGroup(groupText, "", 1, 2);
		this.domainCombo = CompositeFactory.createReadOnlyCombo(this,
				selectGroup, Properties.diagram_label_table_column_datatype,
				this.getNumColumns() - 1, -1);

		initRadio();
	}

	@Override
	protected void setData() {

		// 数据类型
		String[] dataType = DataTypeUtils.getDataType();
		this.dataTypeCombo.setItems(dataType);

		// domain
		String[] domains = domainSet.toStringArray();
		if (null != domains && domains.length > 0) {
			this.domainCombo.setItems(domains);
		}

		// 编辑
		if (!this.add) {
			// 主键
			this.primaryKeyCheck.setSelection(this.targetColumn.getPrimary());
			// 不允许为空
			if (this.primaryKeyCheck.getSelection()) {
				this.notNullCheck.setSelection(true);
				this.notNullCheck.setEnabled(false);
			} else {
				this.notNullCheck.setSelection(this.targetColumn.getMandatory());
			}
			// 编码
			this.codeText.setText(this.targetColumn.getCode());
			// 名称
			this.nameText.setText(this.targetColumn.getName());
			// 注释
			this.commentText.setText(this.targetColumn.getComment());
			// 基本类型
			if (!this.targetColumn.hasDomain()) {
				this.domainRadio.setSelection(false);
				this.dataTypeRadio.setSelection(true);
				int index = this.getDataTypeIndex(
						this.targetColumn.getDataType(), dataType);
				this.dataTypeCombo.select(index);
				if(null != this.targetColumn.getLength()){
					this.lengthText.setText(String.valueOf(this.targetColumn.getLength()));
				}
				if(null != this.targetColumn.getPrecision()){
					this.precisionText.setText(String.valueOf(this.targetColumn.getPrecision()));
				}
				
			} else {
				// 域
				this.domainRadio.setSelection(true);
				this.dataTypeRadio.setSelection(false);
				this.domainCombo.select(domainSet
						.getIndexById(this.targetColumn.getDomain()));
			}

		}
	}

	@Override
	protected String getErrorMessage() {
		// code name不可以为空
		String code = this.codeText.getText().trim();
		String name = this.nameText.getText().trim();
		if (code.equals("")) {
			return Properties.error_code_empty;
		}

		if (name.equals("")) {
			return Properties.error_domain_name_empty;
		}

		if (!isUnqName()) {
			return Properties.error_column_unq;
		}
		if (!isUnqCode()) {
			return Properties.error_column_unq;
		}

		boolean isDomain = this.domainRadio.getSelection();
		if (isDomain) {
			if (this.domainCombo.getItems().length == 0) {
				return Properties.error_column_domain_null;
			}
		}

		// 长度、精度不为空的时候　一定为数值类型
		String length = this.lengthText.getText().trim();
		String precision = this.precisionText.getText().trim();

		if (!length.equals("null")) {
			if (!length.equals("")) {
				try {
					Integer.parseInt(length);
				} catch (NumberFormatException e) {
					return Properties.error_domain_length_degit;
				}
			}
		}
		if (!precision.equals("null")) {
			if (!precision.equals("")) {
				try {
					Integer.parseInt(precision);
				} catch (NumberFormatException e) {
					return Properties.error_domain_length_degit;
				}
			}
		}

		return null;
	}

	@Override
	protected void perfomeOK() throws Exception {
		boolean pk = this.primaryKeyCheck.getSelection();
		boolean notNull = this.notNullCheck.getSelection();

		String code = this.codeText.getText().trim();
		String name = this.nameText.getText().trim();
		String comment = this.commentText.getText().trim();

		boolean isDatatype = this.dataTypeRadio.getSelection();
		String dataType = null;
		String length = null;
		String precision = null;

		boolean isDomain = this.domainRadio.getSelection();
		String domain = null;

		this.returnColumn.setMandatory(notNull);
		this.returnColumn.setPrimary(pk);

		if (null != this.targetColumn) {
			this.returnColumn.setId(this.targetColumn.getId());
		} else {
			this.returnColumn.setId(Utils.getUUID());
		}

		this.returnColumn.setCode(code);
		this.returnColumn.setName(name);
		this.returnColumn.setComment(comment);

		if (isDatatype) {
			dataType = this.getSelectedDataType();
			length = this.lengthText.getText().trim();
			precision = this.precisionText.getText().trim();

			this.returnColumn.setDataType(dataType);
			if (!length.equals("") && !length.equals("null")) {
				this.returnColumn.setLength(Integer.parseInt(length));
			}
			if (!precision.equals("") && !precision.equals("null")) {
				this.returnColumn.setPrecision(Integer.parseInt(precision));
			}
		}

		if (isDomain) {
			domain = this.getSelectedDomain();
			this.returnColumn.setDomainObject(copyDomain);
			this.returnColumn.setDomain(domain);
		}

	}

	@Override
	protected String getTitle() {
		return Properties.diagram_label_table_column_add;
	}

	private void initRadio() {
		dataTypeRadio.setSelection(true);
		this.selectGroup.setEnabled(false);
	}

	@Override
	protected void addListener() {
		super.addListener();

		dataTypeRadio.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				super.widgetSelected(e);

				// 清空设置
				domainCombo.deselectAll();

				selectGroup.setEnabled(false);
				inputGroup.setEnabled(true);
			}
		});

		domainRadio.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				super.widgetSelected(e);

				// 　清空设置
				dataTypeCombo.deselectAll();
				lengthText.setText("");
				precisionText.setText("");

				selectGroup.setEnabled(true);
				inputGroup.setEnabled(false);

				// 默认选中第一个domain项
				domainCombo.select(1);
			}
		});

		primaryKeyCheck.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				super.widgetSelected(e);

				isPk = primaryKeyCheck.getSelection();

				if (isPk) {
					notNullCheck.setSelection(true);
					notNullCheck.setEnabled(false);
				} else {
					notNullCheck.setSelection(false);
					notNullCheck.setEnabled(true);
				}
			}

		});
	}

	protected String getSelectedDataType() {
		int index = this.dataTypeCombo.getSelectionIndex();
		if (index > -1) {
			return DataTypeUtils.getDataType()[index];
		}
		return "";
	}

	protected String getSelectedDomain() {
		int index = this.domainCombo.getSelectionIndex();
		if (index > -1) {
			String option = this.domainCombo.getItems()[index];
			Iterator<Domain> iter = domainSet.iterator();
			while (iter.hasNext()) {
				Domain domain = iter.next();
				if (domain.getName().equals(option)) {
					this.copyDomain = domain;
					return domain.getId();
				}
			}
		}
		return "";
	}

	public Column getColumn() {
		return this.returnColumn;
	}

	public void setAdd(boolean add) {
		this.add = add;
	}

	private int getDataTypeIndex(String option, String[] dataType) {
		if (null == option) {
			return -1;
		}
		for (int i = 0; i < dataType.length; i++) {
			if (option.equals(dataType[i])) {
				return i;
			}
		}
		return -1;
	}

	private boolean isUnqName() {
		if (null != this.targetColumnList && this.targetColumnList.size() > 0) {
			for (Column column : targetColumnList) {
				if (column.getName().equals(this.nameText.getText().trim())
						&& !column.getId().equals(this.targetColumn.getId())) {
					return false;
				}
			}
		}
		return true;
	}

	private boolean isUnqCode() {
		if (null != this.targetColumnList && this.targetColumnList.size() > 0) {
			for (Column column : targetColumnList) {
				if (column.getCode().equals(this.codeText.getText().trim())
						&& !column.getId().equals(this.targetColumn.getId())) {
					return false;
				}
			}
		}
		return true;
	}

}
